package br.com.games.pyx.atores;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.entity.Entity;
import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.shape.IShape;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.input.touch.TouchEvent;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

/**
 * Representa um ator na cena.
 * 
 * @author abraao
 *
 */
public abstract class Ator extends Entity implements IShape {
	
	private AnimatedSprite actual;
	private HashMap<Integer, AnimatedSprite> anims = new HashMap<Integer, AnimatedSprite>(); 
	private AtorUpdateHandler updateHandler;
	private IShape shape;
	
	public Ator() {
		
		updateHandler = new AtorUpdateHandler();
		this.registerUpdateHandler(updateHandler);
	}
	
	public void init() {
		create();
		setActual(0);
		
		this.shape = initShape();
	}
	
	protected abstract IShape initShape();

	public IShape getShape() {
		return shape;
	}
	
	class AtorUpdateHandler implements IUpdateHandler {
		
		@Override
		public void onUpdate(float pSecondsElapsed) {
			actual.onUpdate(pSecondsElapsed);
			actual.setPosition(Ator.this);
		}

		@Override
		public void reset() {
		}
		
	}
	
	public void addAnimation(Integer n, AnimatedSprite anim) {
		anims.put(n, anim);
	}
	
	protected void doDraw(final GL10 pGL, final Camera pCamera) {
		actual.onDraw(pGL, pCamera);
	}
	
	public void setActual(int n) {
		this.actual = anims.get(n);
	}
	
	public AnimatedSprite getActual() {
		return actual;
	}
	
	/**
	 * Cria os atores
	 */
	protected abstract void create();

	public abstract void registerBody(PhysicsWorld world);
	
	public void registerBody(PhysicsWorld world, float pDensity, float pElasticity, float pFriction, boolean updatePos, boolean updateRot) {
		
		final FixtureDef fixureDef = PhysicsFactory.createFixtureDef(pDensity, pElasticity, pFriction);// 1,0.5,0.5
		Body body = PhysicsFactory.createBoxBody(world, this, BodyType.DynamicBody, fixureDef);
		
		world.registerPhysicsConnector(new PhysicsConnector(this, body, updatePos, updateRot));//true, false
	}
	
	//SHAPE
	
	@Override
	public void setPosition(final IEntity pOtherEntity) {
		super.setPosition(pOtherEntity);
		shape.setPosition(pOtherEntity);
	}
	
	@Override
	public void setPosition(final float pX, final float pY) {
		super.setPosition(pX, pY);
		shape.setPosition(pX, pY);		
	}
	
	@Override
	public boolean isCullingEnabled() {
		return shape.isCullingEnabled();
	}


	@Override
	public void setCullingEnabled(boolean pCullingEnabled) {
		shape.setCullingEnabled(pCullingEnabled);
	}


	@Override
	public float getWidth() {
		return shape.getWidth();
	}


	@Override
	public float getHeight() {
		return shape.getHeight();
	}


	@Override
	public float getBaseWidth() {
		return shape.getBaseWidth();
	}


	@Override
	public float getBaseHeight() {
		return shape.getBaseHeight();
	}


	@Override
	public float getWidthScaled() {
		return shape.getWidthScaled();
	}


	@Override
	public float getHeightScaled() {
		return shape.getHeightScaled();
	}


	@Override
	public boolean collidesWith(IShape pOtherShape) {
		return shape.collidesWith(pOtherShape);
	}


	@Override
	public void setBlendFunction(int pSourceBlendFunction, int pDestinationBlendFunction) {
		shape.setBlendFunction(pSourceBlendFunction, pDestinationBlendFunction);
	}


	@Override
	public boolean contains(float pX, float pY) {
		return shape.contains(pX, pY);
	}


	@Override
	public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
			float pTouchAreaLocalX, float pTouchAreaLocalY) {
		return false;
	}	
}
